package com.ly.demo.config;

import cn.hutool.json.JSONUtil;
import com.ly.demo.annotation.RedisListener;
import com.ly.demo.entity.UserEntity;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.data.redis.listener.ChannelTopic;
import org.springframework.data.redis.listener.RedisMessageListenerContainer;
import org.springframework.stereotype.Component;

import javax.annotation.PostConstruct;
import java.io.UnsupportedEncodingException;
import java.lang.reflect.Method;
import java.net.URLDecoder;
import java.util.HashMap;
import java.util.Map;

@Component
public class RedisMessageListenerManager {

    private final RedisMessageListenerContainer redisMessageListenerContainer;
    private final ApplicationContext applicationContext;

    private final Map<String, Method> listenerMethods = new HashMap<>();

    @Autowired
    public RedisMessageListenerManager(RedisMessageListenerContainer redisMessageListenerContainer,
                                       ApplicationContext applicationContext) {
        this.redisMessageListenerContainer = redisMessageListenerContainer;
        this.applicationContext = applicationContext;
    }

    @PostConstruct
    public void initializeListeners() {
        String[] beanNames = applicationContext.getBeanNamesForType(Object.class);
        for (String beanName : beanNames) {
            Class<?> beanType = applicationContext.getType(beanName);
            for (Method method : beanType.getDeclaredMethods()) {
                if (method.isAnnotationPresent(RedisListener.class)) {
                    RedisListener redisListener = method.getAnnotation(RedisListener.class);
                    String topic = redisListener.topic();
                    if (!listenerMethods.containsKey(topic)) {
                        listenerMethods.put(topic, method);
                        Object beanInstance = applicationContext.getBean(beanName);
                                redisMessageListenerContainer.addMessageListener(
                                (message, pattern) -> invokeListenerMethod(beanInstance, method, message),
                                new ChannelTopic(topic)
                        );
                    }
                }
            }
        }
    }



    private void invokeListenerMethod(Object beanInstance, Method method, org.springframework.data.redis.connection.Message message) {
        try {
            String payload = new String(message.getBody());
            method.invoke(beanInstance, payload);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}